package main

import (
	"fmt"
	"gitee.com/pdudo/SampleHttp"
	"strings"
	"sync"
	"time"
)

// 在指定时间限制访问次数设置
const (
	maxNum = 10 // 在指定时间内最多允许访问的次数为10次
	interval = 1 // 设置指定时间, 最短为1分钟
)

// 定义访问结构体
type visitInfo struct {
	number uint64
	createUnixTime int64
}

// 定义访问map
var visitHashMap map[string]visitInfo
// 定义锁
var lock sync.Mutex

func limits(ip string)(bool) {
	visit, ok := visitHashMap[ip]; if !ok {
		// 如果没有该ip的访问次数,则新增记录
		func() {
			lock.Lock()
			defer lock.Unlock()
			visitHashMap[ip] = visitInfo{number: 0, createUnixTime: time.Now().Unix()}
		}()
		return true
	} else {
		// 判断是否限流
		return func() (bool) {
			lock.Lock()
			defer lock.Unlock()

			// 查看是否超过指定时间
			if time.Now().Unix()-visit.createUnixTime >= interval*60 {
				delete(visitHashMap, ip)
				return true
			}

			// 访问次数+1
			visit.number++
			visitHashMap[ip] = visit

			// 查看是否超过允许最大访问次数
			if visit.number >= maxNum {
				return false
			}
			return true
		}()
	}
}

func main() {
	SampleHttp.Route("get","/queryAll", func(info *SampleHttp.HttpInfo) {
		ip := strings.Split(info.RemoteIP,":")[0]
		if ! limits(ip) {
			info.Write([]byte(fmt.Sprintf("%s 已经被限制访问，在%d分钟内，访问达到%d次",time.Now(),interval,visitHashMap[ip].number)))
			return
		}
		info.Write([]byte(fmt.Sprintf("%s 收到queryAll请求,开始查询,返回1W字节数据信息...,统计信息: 在%d分钟内，访问达到%d次",time.Now(),interval,visitHashMap[ip].number)))
	})

	visitHashMap = make(map[string]visitInfo,0)
	SampleHttp.StartServer("0.0.0.0:8083")
}